package com.leyou.search.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.clients.ItemClient;
import com.leyou.item.dto.CategoryDTO;
import com.leyou.item.dto.SpecParamDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.search.pojo.Goods;
import com.leyou.search.repository.GoodsRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class IndexService {

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private GoodsRepository goodsRepository;

    //数据加工，
    //所谓的数据倒入不就是把spu转换为goods
    public Goods buildGoods(SpuDTO spuDTO) {
        Goods goods = BeanHelper.copyProperties(spuDTO, Goods.class);

        goods.setCategoryId(spuDTO.getCid3());

        goods.setCreateTime(spuDTO.getCreateTime().getTime());

        StringBuilder stb = new StringBuilder();

        stb.append(spuDTO.getName());
        //all spuName categoryName brandName
        String categoryNames = this.itemClient.queryCategoryByIds(spuDTO.getCategoryIds())
                .stream()
                .map(CategoryDTO::getName)
                .collect(Collectors.joining(" "));

        stb.append(categoryNames);

        //TODO stb.append(brandName)
        goods.setAll(stb.toString());


        //skus

        Set<Long> prices = new HashSet<>();

        //跨服务根据spuId查询sku，并从sku的多个属性中取出4个
        List<Map<String, Object>> skuMaps = this.itemClient.querySkuBySpuId(spuDTO.getId())
                .stream()
                .map(skuDTO -> {
                    Map<String, Object> skuMap = new HashMap<>();
                    skuMap.put("id", skuDTO.getId());
                    skuMap.put("title", skuDTO.getTitle());
                    skuMap.put("price", skuDTO.getPrice());
                    //以,为分界线，取出第一个,之前的内容
                    skuMap.put("image", StringUtils.substringBefore(skuDTO.getImages(), ","));

                    //取出每个价格，存入set集合
                    prices.add(skuDTO.getPrice());
                    return skuMap;
                }).collect(Collectors.toList());

        //obj-->str
        goods.setSkus(JsonUtils.toString(skuMaps));

        //price
        goods.setPrice(prices);

        //specs 所有的可搜索规格参数值得key，value

        Map<String,Object> specs = new HashMap<>();

        //specs的key需要查询当前分类的可搜索规格参数
        List<SpecParamDTO> specParamDTOS = this.itemClient.querySpecParams(null, spuDTO.getCid3(), true);


        //根据spuId查询对应的spuDetail
        SpuDetailDTO spuDetailDTO = this.itemClient.querySpuDetailBySpuId(spuDTO.getId());



        //拿通用规格json转为通用规格map，map的key就是可搜索规格参数的id
        Map<Long,Object> genericMap = JsonUtils.nativeRead(spuDetailDTO.getGenericSpec(), new TypeReference<Map<Long, Object>>() {
        });

        //拿特有规格的json，转为特有规格的map，map的key就是可搜索规格参数的id
        Map<Long,List<String>> specailMap = JsonUtils.nativeRead(spuDetailDTO.getSpecialSpec(), new TypeReference<Map<Long, List<String>>>() {
        });


        //循环把分类的可搜索规格参数的名称添加到规格参数的key位置
        specParamDTOS.forEach(specParamDTO -> {
            Long id = specParamDTO.getId();//当前具体的可搜索规格参数的id
            String paramName = specParamDTO.getName();//规格参数的名称

            Object value = null;
            if (specParamDTO.getGeneric()){//通用属性

               value =  genericMap.get(id);
            }else {//特有属性

               value =  specailMap.get(id);
            }

            // 判断是否是数值类型
            if(specParamDTO.getNumeric()){
                // 是数字类型，分段
                value = chooseSegment(value, specParamDTO);
            }
            specs.put(paramName,value);
        });


        goods.setSpecs(specs);

        return goods;
    }

    private String chooseSegment(Object value, SpecParamDTO p) {
        if (value == null || StringUtils.isBlank(value.toString())) {
            return "其它";
        }
        double val = parseDouble(value.toString());
        String result = "其它";
        // 保存数值段
        for (String segment : p.getSegments().split(",")) {
            String[] segs = segment.split("-");
            // 获取数值范围
            double begin = parseDouble(segs[0]);
            double end = Double.MAX_VALUE;
            if (segs.length == 2) {
                end = parseDouble(segs[1]);
            }
            // 判断是否在范围内
            if (val >= begin && val < end) {
                if (segs.length == 1) {
                    result = segs[0] + p.getUnit() + "以上";
                } else if (begin == 0) {
                    result = segs[1] + p.getUnit() + "以下";
                } else {
                    result = segment + p.getUnit();
                }
                break;
            }
        }
        return result;
    }

    private double parseDouble(String str) {
        try {
            return Double.parseDouble(str);
        } catch (Exception e) {
            return 0;
        }
    }

    public void createIndex(Long id) {

        SpuDTO spuDTO = this.itemClient.querySpuById(id);

        Goods goods = buildGoods(spuDTO);

        this.goodsRepository.save(goods);
    }

    public void deleteById(Long id) {
        this.goodsRepository.deleteById(id);
    }
}
